/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package main;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.genew.squadra.xml.model.builder.BuildZip;
import org.genew.squadra.xml.model.builder.ContainerBuilder;
import org.genew.squadra.xml.model.builder.ContentBuilder;
import org.genew.squadra.xml.model.builder.MimeBuilder;
import org.genew.squadra.xml.model.builder.NavBuilder;
import org.genew.squadra.xml.model.builder.TocBuilder;
import org.genew.squadra.xml.model.content.Content;
import org.genew.squadra.xml.model.content.guide.Guide;
import org.genew.squadra.xml.model.content.guide.Reference;
import org.genew.squadra.xml.model.content.manifest.Item;
import org.genew.squadra.xml.model.content.manifest.Manifest;
import org.genew.squadra.xml.model.content.metadati.*;
import org.genew.squadra.xml.model.content.spine.ItemRef;
import org.genew.squadra.xml.model.content.spine.Spine;
import org.genew.squadra.xml.model.epub.EpubFiles;
import org.genew.squadra.xml.model.epub.ToZip;
import org.genew.squadra.xml.model.nav.Nav;
import org.genew.squadra.xml.model.nav.Navhref;
import org.genew.squadra.xml.model.toc.Head;
import org.genew.squadra.xml.model.toc.Navmap;
import org.genew.squadra.xml.model.toc.Navpoint;
import org.genew.squadra.xml.model.toc.Toc;
import org.genew.squadra.xml.model.wellformed.XMLTest;
import org.w3c.dom.Document;
/**
 *
 * @author giona_000
 */
public class EpubLocal {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws UnsupportedEncodingException, XMLStreamException, FileNotFoundException, IOException {
        // TODO code application logic here
        String path ="content.opf";
        Writer w = null;
        
        /**Metadata**/
        Format frmt = new Format("format", "formato");
        Source s = new Source("source", "http://wwww.asd.it");
        Language l = new Language("language", "IT");
        Type t = new Type("type", "xml");
        Data d = new Data("date", new Date());
        Identifier ident = new Identifier("VitellaioID", "isbn:VitellaioID000101010");
        Creator c = new Creator("creator", "Ciufillo", "Italian", "Porco");
        Subject sb = new Subject("Subject", "Ciufillo", "Italian", "Maiale");
        Contributor contributor = new Contributor("Contributor", "Ciufillo", "Italian", "Maiale");
        Relation rl = new Relation("Realtion", "Ciufillo", "Italian", "Vitello");
        Publisher pb = new Publisher("Publisher", "Vitellonia", "Italian", "Maiale");
        Rights rg = new Rights("Rights", "Ciufillo", "Italian", "Maiale");
        Coverage cv = new Coverage("Coverage", "ASD", "Italian", "Porco");
        Description dsc = new Description("Descr", "Vitellonia", "Italian", "Maiale");
        Title tl = new Title("Title", "Il Vitellaio magico", "Italian", "Maiale");
        
        Metadata mtd = new Metadata(frmt, s, l, t, d, ident, c, sb, contributor, rl, pb, rg, cv, dsc, tl);
        
        /**Fine MEtatada**/
        List<String> Lista = new ArrayList<String>();
        Lista.add("p01.xhtml");
        Lista.add("p02.xhtml");
        for (String Capitolo : Lista) {
            
            if( XMLTest.loadDocument(Capitolo)==null)  System.err.println("non ben formati");
            
        }
       
        
        /*SPINE*/
        ItemRef itmRefUno = new ItemRef("p01", true, "dafault", "page-spread-left");
        ItemRef itmRefDue = new ItemRef("p02", true, "dafault", "page-spread-right");
        List<ItemRef> lstRef = new ArrayList<>();
        lstRef.add(itmRefUno);
        lstRef.add(itmRefDue);
        Spine spine = new Spine("LaVidaLoca", "ncxtoc", "default", lstRef);
        
        /*END SPINE*/
        
        /*Istanziazione del Manifest*/
        Item itm = new Item("p01","XHTML/p01.xhtml","application/xhtml+xml", "fallback", null, null);
        Item itmDue = new Item("p02","XHTML/p02.xhtml","application/xhtml+xml", "fallback", null, null);
        Item itmTre = new Item("toc","XHTML/nav.xhtml","application/xhtml+xml", null, "nav", null);
        Item itmQ = new Item("ncxtoc","XHTML/toc.ncx","application/x-dtbncx+xml", null, null, null);
        List<Item> lst = new ArrayList<>();
        lst.add(itm);
        lst.add(itmDue);
        lst.add(itmTre);
        lst.add(itmQ);
        Manifest mnf = new Manifest("Prova", lst);
        /*FINE Istanziazione del Manifest*/
        
        /* GUIDE*/
        
//        Reference reference = new Reference("preface", "King", "http://www.google.it");
//        Reference referenceDue = new Reference("title-page", "King of Babylon", "http://www.sportmediaset.it/");
//        List<Reference> rlst = new ArrayList<>();
//        rlst.add(reference);
//        rlst.add(referenceDue);
//        Guide guide = new Guide(rlst);
//        
        /* FINE GUIDE*/
        
        /*Dichiarazione Content */
        Content content = new Content(mtd, mnf, spine, null);
        /*Fine Dichiarazione Content */
         
        /*Dichiarazione degli Elementi di TOc*/
        
        /*NAV POINT E NAV MAP*/
        Navpoint navPoint = new Navpoint("p01", 1, "Capitolo I", "p01.xhtml", null);
        Navpoint navPoint2 = new Navpoint("p02", 2, "Capitolo II", "p02.xhtml", null);
//        Navpoint navPoint3 = new Navpoint("cp03", 3, "Capitolo III", "p03.xhtml", null);
        List<Navpoint> navList = new ArrayList<>();
        navList.add(navPoint);
        navList.add(navPoint2);
//        navList.add(navPoint3);
                
        Navmap navMap = new Navmap(navList);
        
        /* FINE NAV POINT E NAV MAP*/
        /*HEAD*/
        Head head = new Head(mtd.getIdentifier().getValue(), -1, navMap.getNavpoints().size(), 3);
        
        /*FINE HEAD*/
        /*TOC*/
        Toc toc = new Toc(head, "Il Vitellaio Magico", "Ciufillo", navMap);
        /*FINE TOC*/
        /*Fine Dichiarazione degli Elementi di TOc*/
        
        
        
        XMLStreamWriter xmlv= null;
        
        try {
//            /*OPF*/
            w = new OutputStreamWriter(new FileOutputStream(path), "UTF-8");
            XMLOutputFactory f = XMLOutputFactory.newInstance();
            xmlv = f.createXMLStreamWriter(w);
            ContentBuilder.buildOpf(content,xmlv);
            /*FINE OPF*/

        /*Metadata
            xmlns:opf="http://www.idpf.org/2007/opf"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:dcterms="http://purl.org/dc/terms/"
         */
 
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EpubLocal.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try{
                if (xmlv != null) xmlv.close();
                if (w != null) w.close();
            } catch(XMLStreamException | IOException ex){
                System.out.println("TOP");
            }
        }
        
        /*Inizializazzione del TOC*/
        String pathToc = "toc.ncx";
        XMLStreamWriter xmlToc= null; //Dato uno stream di OutPut, XMLStreamWriter Scriverà codice XML
        Writer wToc = null; //Questo serve per scrivere il file su un determinato path
        /*Fine Toc*/
        
        try {
            wToc = new OutputStreamWriter(new FileOutputStream(pathToc), "UTF-8");
            XMLOutputFactory fToc = XMLOutputFactory.newInstance();
            xmlToc = fToc.createXMLStreamWriter(wToc);
            TocBuilder.buildToc(toc, xmlToc);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EpubLocal.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try{
                if (xmlToc != null) xmlToc.close();
                if (wToc != null) wToc.close();
            } catch(XMLStreamException | IOException ex){
                System.out.println("TOP");
            }
        }
        /*Inizializazzione del TOC*/
        
        /*NavHref*/
        Navhref navhrefUno = new Navhref("p01", "chapter", "p01.xhtml","Capitolo I");
        Navhref navhrefDue = new Navhref("p02", "chapter", "p02.xhtml","Capitolo II");
        List<Navhref> lNavH = new ArrayList<>();
        lNavH.add(navhrefUno);
        lNavH.add(navhrefDue);
        /*Fine NavHref*/
        /*Nav*/
        
        Nav nav = new Nav("Il Vitellaio Magico", lNavH);
        /*Fine Nav*/
                
        String pathNav = "nav.xhtml";
        XMLStreamWriter xmlNav= null; //Dato uno stream di OutPut, XMLStreamWriter Scriverà codice XML
        Writer wNav = null; //Questo serve per scrivere il file su un determinato path
        /*Fine Toc*/
        try {
            
            wNav = new OutputStreamWriter(new FileOutputStream(pathNav), "UTF-8");
            XMLOutputFactory fNav = XMLOutputFactory.newInstance();
//            System.out.println(wNav);
            xmlNav = fNav.createXMLStreamWriter(wNav);
            
            NavBuilder.buildNav(nav, xmlNav);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EpubLocal.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try{
                if (xmlNav != null) xmlNav.close();
                if (wNav != null) wNav.close();
            } catch(XMLStreamException | IOException ex){
                System.out.println("TOP");
            }
        }
        
        /*Container.xml e MimeType!*/
        String pathCont = "container.xml";
        XMLStreamWriter xmlContainer= null; 
        Writer wCont = null;
        try {
            wCont = new OutputStreamWriter(new FileOutputStream(pathCont), "UTF-8");
            XMLOutputFactory fCont = XMLOutputFactory.newInstance();
            xmlContainer = fCont.createXMLStreamWriter(wCont);
            ContainerBuilder.buildContainer("OPS/content.opf", xmlContainer);
           
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EpubLocal.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try{
                if (xmlContainer != null) xmlContainer.close();
                if (wCont != null) wCont.close();
            } catch(XMLStreamException | IOException ex){
                System.out.println("TOP");
            }
        }  
        
//         try {
//            //MimeType
////            MimeBuilder.buildMime();
//           
//        } catch (FileNotFoundException e){
//            System.out.println("fuck");}
        /*Fine Container xml e MimeType*/
        
        
        //Scrittura ZIP
        List<EpubFiles> file_da_zippare = new ArrayList<EpubFiles>();
            file_da_zippare.add(new EpubFiles("mimetype", ""));
            file_da_zippare.add(new EpubFiles("content.opf", "OPS/"));
            file_da_zippare.add(new EpubFiles("toc.ncx", "OPS/XHTML/"));
            file_da_zippare.add(new EpubFiles("nav.xhtml", "OPS/XHTML/"));
            file_da_zippare.add(new EpubFiles("container.xml", "META-INF/"));
            file_da_zippare.add(new EpubFiles("p01.xhtml", "OPS/XHTML/"));
            file_da_zippare.add(new EpubFiles("p02.xhtml", "OPS/XHTML/"));    
            ToZip toZip = new ToZip(file_da_zippare);
            BuildZip.buildEpub(toZip, "IlVitellaioMagico.epub");
//        FileOutputStream output = new FileOutputStream("IlVitellaioMagico.zip");    //Crea il file di OutPut
//        try (ZipOutputStream zOs = new ZipOutputStream(new BufferedOutputStream(output))) {  //tenta di creare uno Sream di output per scrivere i file
//            
//            zOs.setMethod(ZipOutputStream.DEFLATED); //Non so che fa ma si us
//            
//            /*file da zippare*/
//            List<String> file_da_zippare = new ArrayList<>();
//            file_da_zippare.add("mimetype");
//            file_da_zippare.add("content.opf");
//            file_da_zippare.add("toc.ncx");
//            file_da_zippare.add("nav.xhtml");
//            file_da_zippare.add("container.xml");
//            
//            /*fine file da zippare*/
//            
//            for (String file_da_zippare1 : file_da_zippare) {
//                
//                FileInputStream fi = new FileInputStream(file_da_zippare1); //Legge i file
//                byte data[] = new byte[1024];   //Array di byte per dare una unità di misurà per la lettura
//                // Creare uno ZipEntry per il file in questione:
//                ZipEntry entry = new ZipEntry(file_da_zippare1); // crea una entry del file da zippare, non so che fà ma senza non worka
//                BufferedInputStream input = null;
//                input = new BufferedInputStream(fi, 1024);  //Input è lo stream da file 1 byte alla volta
//                zOs.putNextEntry(entry);    //Dunno
//                int count;
//                while((count = input.read(data, 0, 1024)) != -1){
//                    zOs.write(data, 0, count); //Scrivi sullo stream Output
//                }
//                input.close(); // chiudi stream dal file
//                
//            }
//        }
    }
    
}
